/*
 * Copyright (c) 2018, apexes.net. All rights reserved.
 *
 *         http://www.apexes.net
 *
 */
package net.apexes.commons.xml;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.nio.charset.Charset;
import java.nio.file.Files;

/**
 * @author <a href="mailto:hedyn@foxmail.com">HeDYn</a>
 */
public final class Xmls {

    private Xmls() {
    }

    public static XmlElement node(XmlElement xml, String path) {
        if (!path.startsWith("/")) {
            path = "/" + path;
        }
        String start = "/" + xml.getName() + "/";
        if (!path.startsWith(start)) {
            return null;
        }
        path = path.replaceFirst(start, "");
        String[] nodes = path.split("/");
        for (String node : nodes) {
            xml = xml.getChild(node);
            if (xml == null) {
                return null;
            }
        }
        return xml;
    }

    public static String nodeContent(XmlElement xml, String path) {
        xml = node(xml, path);
        if (xml == null) {
            return null;
        }
        return xml.getContent();
    }

    public static String nodeAttr(XmlElement xml, String path, String name) {
        xml = node(xml, path);
        if (xml == null) {
            return null;
        }
        return xml.getStringAttribute(name);
    }

    public static String nodeAttr(XmlElement xml, String path,
                                  String name, String defaultValue) {
        xml = node(xml, path);
        if (xml == null) {
            return null;
        }
        return xml.getStringAttribute(name, defaultValue);
    }

    public static XmlElement xml(String xml) {
        XmlElement x = new XmlElement();
        x.parseString(xml);
        return x;
    }

    public static XmlElement xml(File xmlFile, Charset charset) throws IOException {
        return xml(xmlFile, charset.name());
    }

    public static XmlElement xml(File xmlFile, String charsetName) throws IOException {
        try (InputStream in = Files.newInputStream(xmlFile.toPath())) {
            return xml(in, charsetName);
        }
    }

    public static XmlElement xml(InputStream input, Charset charset) throws IOException {
        return xml(input, charset.name());
    }

    public static XmlElement xml(InputStream input, String charsetName) throws IOException {
        InputStreamReader reader = new InputStreamReader(input, charsetName);
        return xml(reader);
    }

    public static XmlElement xml(Reader reader) throws IOException {
        XmlElement xml = new XmlElement(true);
        xml.parseFromReader(reader);
        return xml;
    }

    public static void save(XmlElement xml, File xmlFile, Charset charset) throws IOException {
        save(xml, xmlFile, charset.name());
    }

    public static void save(XmlElement xml, File xmlFile, String charsetName) throws IOException {
        try (OutputStream outputStream = Files.newOutputStream(xmlFile.toPath())) {
            save(xml, outputStream, charsetName);
        }
    }

    public static void save(XmlElement xml, OutputStream outputStream, Charset charset) throws IOException {
        Writer writer = new OutputStreamWriter(outputStream, charset);
        xml.write(writer, true, 4);
        writer.flush();
    }

    public static void save(XmlElement xml, OutputStream outputStream, String charsetName) throws IOException {
        Writer writer = new OutputStreamWriter(outputStream, charsetName);
        xml.write(writer, true, 4);
        writer.flush();
    }
}